package com.advertisementsystem.Servie.Impl;

import com.advertisementsystem.Dto.LoginUser;
import com.advertisementsystem.Exception.BusinessException;
import com.advertisementsystem.Mapper.AdNegotiationMapper;
import com.advertisementsystem.Mapper.AdvertisementMapper;
import com.advertisementsystem.Mapper.BillMapper;
import com.advertisementsystem.Mapper.UserMapper;
import com.advertisementsystem.Servie.BillService;
import com.advertisementsystem.entity.AdNegotiation;
import com.advertisementsystem.entity.Advertisement;
import com.advertisementsystem.entity.Bill;

import com.advertisementsystem.entity.User;
import com.advertisementsystem.utils.AuthContextHolder;
import com.advertisementsystem.vo.BillVO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
@Service
public class BillServiceImpl implements BillService {

    @Autowired
    private BillMapper billMapper;

    @Autowired
    private AdNegotiationMapper negotiationMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private AdvertisementMapper advertisementMapper;

    @Override
    public IPage<BillVO> getBills(Integer pageNum, Integer pageSize, String status, String keyword) {


        // 获取当前用户
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        // 根据用户角色决定如何查询
        Long advertiserId = null;
        Long deviceOwnerId = null;

        if (loginUser.getPermissions().contains("ROLE_ADVERTISER")) {
            advertiserId = loginUser.getUser().getId();
        } else if (loginUser.getPermissions().contains("ROLE_DEVICE_OWNER")) {
            deviceOwnerId = loginUser.getUser().getId();
        }
        // 创建分页对象
        Page<Bill> page = new Page<>(pageNum, pageSize);



        // 执行查询
        IPage<Bill> billPage = billMapper.getBillsWithDetails(page, status, advertiserId, deviceOwnerId, keyword);

        // 转换为VO对象
        return billPage.convert(this::convertToVO);
    }

    @Override
    public BillVO getBillDetail(Long id) {
        // 获取账单详情
        Bill bill = billMapper.getBillWithDetailsById(id);
        if (bill == null) {
            throw new BusinessException("账单不存在");
        }

        // 获取当前用户
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();
        // 根据用户角色决定如何查询
        Long advertiserId = null;
        Long deviceOwnerId = null;

        if (loginUser.getPermissions().contains("ROLE_ADVERTISER")&& !bill.getAdvertiserId().equals(loginUser.getUser().getId())) {
            throw new BusinessException("无权查看此账单");
        } else if (loginUser.getPermissions().contains("ROLE_DEVICE_OWNER")&&!bill.getDeviceOwnerId().equals(loginUser.getUser().getId())) {
            throw new BusinessException("无权查看此账单");
        }


        return convertToVO(bill);
    }

    @Override
    @Transactional
    public void payBill(Long id, String paymentMethod) {
        Bill bill = billMapper.selectById(id);
        if (bill == null) {
            throw new BusinessException("账单不存在");
        }

        // 检查账单状态
        if ("PAID".equals(bill.getStatus())) {
            throw new BusinessException("账单已支付，无需重复支付");
        }

        // 获取当前用户
        LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext()
                .getAuthentication()
                .getPrincipal();

        if (!loginUser.getPermissions().contains("ROLE_ADVERTISER")&& !bill.getAdvertiserId().equals(loginUser.getUser().getId())) {
            throw new BusinessException("只有广告主可以支付账单");
        }

        // 更新账单状态
        bill.setStatus("PAID");
        bill.setPaymentDate(LocalDateTime.now());
        bill.setUpdatedTime(LocalDateTime.now());
        bill.setPaymentMethod(paymentMethod);

        billMapper.updateById(bill);

        // 这里可以添加支付成功后的业务逻辑，如发送通知等
    }

    @Override
    @Transactional
    public void createBill(Long negotiationId) {
        // 查询协商信息
        AdNegotiation negotiation = negotiationMapper.selectById(negotiationId);
        if (negotiation == null) {
            throw new BusinessException("协商不存在");
        }

        // 检查协商状态
        if (negotiation.getStatus() != 1) {
            throw new BusinessException("只有已完成的协商才能生成账单");
        }

        // 检查是否已存在账单
        QueryWrapper<Bill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("negotiation_id", negotiationId);
        if (billMapper.selectCount(queryWrapper) > 0) {
            throw new BusinessException("该协商已生成账单");
        }

        // 创建账单
        Bill bill = new Bill();
        bill.setNegotiationId(negotiationId);
        bill.setAdvertiserId(negotiation.getAdvertiserId());
        bill.setDeviceOwnerId(negotiation.getDeviceOwnerId());
        bill.setAmount(negotiation.getPrice());
        bill.setStatus("UNPAID");

        // 设置支付期限为30天后
        bill.setDueDate(LocalDateTime.now().plusDays(30));
        bill.setCreatedTime(LocalDateTime.now());
        bill.setUpdatedTime(LocalDateTime.now());

        billMapper.insert(bill);
    }

    @Override
    @Transactional
    public void updateOverdueBills() {
        // 查询所有已过期但仍显示未支付的账单
        QueryWrapper<Bill> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", "UNPAID")
                .lt("due_date", LocalDateTime.now());

        List<Bill> overdueBills = billMapper.selectList(queryWrapper);

        for (Bill bill : overdueBills) {
            bill.setStatus("OVERDUE");
            bill.setUpdatedTime(LocalDateTime.now());
            billMapper.updateById(bill);
        }
    }

    /**
     * 将实体对象转换为VO对象
     */
    private BillVO convertToVO(Bill bill) {
        if (bill == null) {
            return null;
        }

        BillVO vo = new BillVO();
        BeanUtils.copyProperties(bill, vo);

        // 获取广告主信息
        if (bill.getAdvertiserId() != null) {
            User advertiser = userMapper.selectById(bill.getAdvertiserId());
            if (advertiser != null) {
                vo.setAdvertiserName(advertiser.getNickname());
            } else {
                vo.setAdvertiserName("未知广告主");
                log.warn("未找到ID为{}的广告主", bill.getAdvertiserId());
            }
        }

        // 获取设备主信息
        if (bill.getDeviceOwnerId() != null) {
            User deviceOwner = userMapper.selectById(bill.getDeviceOwnerId());
            if (deviceOwner != null) {
                vo.setDeviceOwnerName(deviceOwner.getNickname());
            } else {
                vo.setDeviceOwnerName("未知设备主");
                log.warn("未找到ID为{}的设备主", bill.getDeviceOwnerId());
            }
        }

        LambdaQueryWrapper<AdNegotiation> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(AdNegotiation::getId, bill.getNegotiationId());
        AdNegotiation negotiation = negotiationMapper.selectOne(queryWrapper);
        // 获取广告信息
        if (negotiation.getAdId() != null) {
            Advertisement advertisement = advertisementMapper.selectById(negotiation.getAdId());
            if (advertisement != null) {
                vo.setAdvertisementName(advertisement.getTitle());
            } else {
                vo.setAdvertisementName("未知广告");
                log.warn("未找到ID为{}的广告", negotiation.getAdId());
            }
        }

        return vo;
    }
}